package org.eclipse.moquette.server.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import org.eclipse.moquette.server.Constants;
import org.eclipse.moquette.server.ServerChannel;


/**
 * 实现ServerChannel 完成会话的初始化
 * Created by alex on 15-5-30.
 */
public class NettyChannel implements ServerChannel {

    private ChannelHandlerContext m_channel;

    //mqtt会话的keepAlive
    public static final AttributeKey<Object> ATTR_KEY_KEEPALIVE = AttributeKey.valueOf(Constants.KEEP_ALIVE);
    //mqtt会话断开后是否clean_session
    public static final AttributeKey<Object> ATTR_KEY_CLEANSESSION = AttributeKey.valueOf(Constants.CLEAN_SESSION);
    //mqtt会话的clientID
    public static final AttributeKey<Object> ATTR_KEY_CLIENTID = AttributeKey.valueOf(Constants.ATTR_CLIENTID);

    NettyChannel(ChannelHandlerContext ctx) {
        m_channel = ctx;
    }

    @Override
    public Object getAttribute(AttributeKey<Object> key) {
        Attribute<Object> attr = m_channel.attr(key);
        return attr.get();
    }

    @Override
    public void setAttribute(AttributeKey<Object> key, Object value) {
        Attribute<Object> attr = m_channel.attr(key);
        attr.set(value);
    }

    /**
     * 设置心跳的频率
     * @param idleTime
     */
    @Override
    public void setIdleTime(int idleTime) {
        if (m_channel.pipeline().names().contains("idleStateHandler")) {
            m_channel.pipeline().remove("idleStateHandler");
        }
        if (m_channel.pipeline().names().contains("idleEventHandler")) {
            m_channel.pipeline().remove("idleEventHandler");
        }

        m_channel.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, idleTime));
        m_channel.pipeline().addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimoutHandler());
    }

    @Override
    public void close(boolean immediately) {
        m_channel.close();
    }

    @Override
    public void write(Object value) {
        m_channel.writeAndFlush(value);
    }

    @Override
    public String toString() {
        String clientID = (String) getAttribute(ATTR_KEY_CLIENTID);
        return "session [clientID: "+ clientID +"]" + super.toString();
    }
}
